package main

/*
#include <stdint.h>
#include <stdlib.h>

#define LogoutStatus 1
#define Logging 2
#define Logged 3
#define LogoutTips "js sdk socket close"

typedef void (*OnSuccessFn)(void* userData, const char* data);
typedef void (*OnErrorFn)(void* userData, int32_t errCode, const char* errMsg);
typedef void (*OnProgressFn)(void* userData, int progress);

static void CallOnError(OnErrorFn fn, void* userData, int32_t errCode, const char* errMsg) {
    if (fn != NULL) {
        fn(userData, errCode, errMsg);
    }
}
static void CallOnSuccess(OnSuccessFn fn, void* userData, const char* data) {
    if (fn != NULL) {
        fn(userData, data);
    }
}
static void CallOnProgress(OnProgressFn fn, void* userData, int progress) {
    if (fn != NULL) {
        fn(userData, progress);
    }
}

typedef struct {
	void* userData;
    OnSuccessFn OnSuccess;
    OnErrorFn OnError;
} BaseCallback;

typedef struct {
	void* userData;
    OnSuccessFn OnSuccess;
    OnErrorFn OnError;
    OnProgressFn OnProgress;
} SendMsgCallback;

typedef void (*OnConnectingFn)(void* userData);
typedef void (*OnConnectSuccessFn)(void* userData);
typedef void (*OnConnectFailedFn)(void* userData, int32_t errCode, const char* errMsg);
typedef void (*OnKickedOfflineFn)(void* userData);
typedef void (*OnUserTokenExpiredFn)(void* userData);
typedef void (*OnUserTokenInvalidFn)(void* userData, const char* errMsg);

static void CallOnConnecting(OnConnectingFn fn, void* userData) {
    if (fn != NULL) {
        fn(userData);
    }
}
static void CallOnConnectSuccess(OnConnectSuccessFn fn, void* userData) {
    if (fn != NULL) {
        fn(userData);
    }
}
static void CallOnConnectFailed(OnConnectFailedFn fn, void* userData, int32_t errCode, const char* errMsg) {
    if (fn != NULL) {
        fn(userData, errCode, errMsg);
    }
}
static void CallOnKickedOffline(OnKickedOfflineFn fn, void* userData) {
    if (fn != NULL) {
        fn(userData);
    }
}
static void CallOnUserTokenExpired(OnUserTokenExpiredFn fn, void* userData) {
    if (fn != NULL) {
        fn(userData);
    }
}
static void CallOnUserTokenInvalid(OnUserTokenInvalidFn fn, void* userData, const char* errMsg) {
    if (fn != NULL) {
        fn(userData, errMsg);
    }
}

typedef struct {
	void* userData;
    OnConnectingFn OnConnecting;
    OnConnectSuccessFn OnConnectSuccess;
    OnConnectFailedFn OnConnectFailed;
    OnKickedOfflineFn OnKickedOffline;
    OnUserTokenExpiredFn OnUserTokenExpired;
    OnUserTokenInvalidFn OnUserTokenInvalid;
} ConnListener;

typedef void (*OnJoinedGroupAddedFn)(void* userData, const char* groupInfo);
typedef void (*OnJoinedGroupDeletedFn)(void* userData, const char* groupInfo);
typedef void (*OnGroupMemberAddedFn)(void* userData, const char* groupMemberInfo);
typedef void (*OnGroupMemberDeletedFn)(void* userData, const char* groupMemberInfo);
typedef void (*OnGroupApplicationAddedFn)(void* userData, const char* groupApplication);
typedef void (*OnGroupApplicationDeletedFn)(void* userData, const char* groupApplication);
typedef void (*OnGroupInfoChangedFn)(void* userData, const char* groupInfo);
typedef void (*OnGroupDismissedFn)(void* userData, const char* groupInfo);
typedef void (*OnGroupMemberInfoChangedFn)(void* userData, const char* groupMemberInfo);
typedef void (*OnGroupApplicationAcceptedFn)(void* userData, const char* groupApplication);
typedef void (*OnGroupApplicationRejectedFn)(void* userData, const char* groupApplication);

static void CallOnJoinedGroupAdded(OnJoinedGroupAddedFn fn, void* userData, const char* groupInfo) {
    if (fn != NULL) {
        fn(userData, groupInfo);
    }
}
static void CallOnJoinedGroupDeleted(OnJoinedGroupDeletedFn fn, void* userData, const char* groupInfo) {
    if (fn != NULL) {
        fn(userData, groupInfo);
    }
}
static void CallOnGroupMemberAdded(OnGroupMemberAddedFn fn, void* userData, const char* groupMemberInfo) {
    if (fn != NULL) {
        fn(userData, groupMemberInfo);
    }
}
static void CallOnGroupMemberDeleted(OnGroupMemberDeletedFn fn, void* userData, const char* groupMemberInfo) {
    if (fn != NULL) {
        fn(userData, groupMemberInfo);
    }
}
static void CallOnGroupApplicationAdded(OnGroupApplicationAddedFn fn, void* userData, const char* groupApplication) {
    if (fn != NULL) {
        fn(userData, groupApplication);
    }
}
static void CallOnGroupApplicationDeleted(OnGroupApplicationDeletedFn fn, void* userData, const char* groupApplication) {
    if (fn != NULL) {
        fn(userData, groupApplication);
    }
}
static void CallOnGroupInfoChanged(OnGroupInfoChangedFn fn, void* userData, const char* groupInfo) {
    if (fn != NULL) {
        fn(userData, groupInfo);
    }
}
static void CallOnGroupDismissed(OnGroupDismissedFn fn, void* userData, const char* groupInfo) {
    if (fn != NULL) {
        fn(userData, groupInfo);
    }
}
static void CallOnGroupMemberInfoChanged(OnGroupMemberInfoChangedFn fn, void* userData, const char* groupMemberInfo) {
    if (fn != NULL) {
        fn(userData, groupMemberInfo);
    }
}
static void CallOnGroupApplicationAccepted(OnGroupMemberInfoChangedFn fn, void* userData, const char* groupApplication) {
    if (fn != NULL) {
        fn(userData, groupApplication);
    }
}
static void CallOnGroupApplicationRejected(OnGroupApplicationRejectedFn fn, void* userData, const char* groupApplication) {
    if (fn != NULL) {
        fn(userData, groupApplication);
    }
}

typedef struct {
	void* userData;
	OnJoinedGroupAddedFn OnJoinedGroupAdded;
	OnJoinedGroupDeletedFn OnJoinedGroupDeleted;
	OnGroupMemberAddedFn OnGroupMemberAdded;
	OnGroupMemberDeletedFn OnGroupMemberDeleted;
	OnGroupApplicationAddedFn OnGroupApplicationAdded;
	OnGroupApplicationDeletedFn OnGroupApplicationDeleted;
	OnGroupInfoChangedFn OnGroupInfoChanged;
	OnGroupDismissedFn OnGroupDismissed;
	OnGroupMemberInfoChangedFn OnGroupMemberInfoChanged;
	OnGroupApplicationAcceptedFn OnGroupApplicationAccepted;
	OnGroupApplicationRejectedFn OnGroupApplicationRejected;
} GroupListener;

typedef void (*OnSyncServerStartFn)(void* userData, int reinstalled);
typedef void (*OnSyncServerFinishFn)(void* userData, int reinstalled);
typedef void (*OnSyncServerProgressFn)(void* userData, int progress);
typedef void (*OnSyncServerFailedFn)(void* userData, int reinstalled);
typedef void (*OnNewConversationFn)(void* userData, const char* conversationList);
typedef void (*OnConversationChangedFn)(void* userData, const char* conversationList);
typedef void (*OnTotalUnreadMessageCountChangedFn)(void* userData, int32_t totalUnreadCount);
typedef void (*OnConversationUserInputStatusChangedFn)(void* userData, const char* change);

static void CallOnSyncServerStart(OnSyncServerStartFn fn, void* userData, int reinstalled) {
    if (fn != NULL) {
        fn(userData, reinstalled);
    }
}
static void CallOnSyncServerFinish(OnSyncServerFinishFn fn, void* userData, int reinstalled) {
    if (fn != NULL) {
        fn(userData, reinstalled);
    }
}
static void CallOnSyncServerProgress(OnSyncServerProgressFn fn, void* userData, int progress) {
    if (fn != NULL) {
        fn(userData, progress);
    }
}
static void CallOnSyncServerFailed(OnSyncServerFailedFn fn, void* userData, int reinstalled) {
    if (fn != NULL) {
        fn(userData, reinstalled);
    }
}
static void CallOnNewConversation(OnNewConversationFn fn, void* userData, const char* conversationList) {
    if (fn != NULL) {
        fn(userData, conversationList);
    }
}
static void CallOnConversationChanged(OnConversationChangedFn fn, void* userData, const char* conversationList) {
    if (fn != NULL) {
        fn(userData, conversationList);
    }
}
static void CallOnTotalUnreadMessageCountChanged(OnTotalUnreadMessageCountChangedFn fn, void* userData, int32_t totalUnreadCount) {
    if (fn != NULL) {
        fn(userData, totalUnreadCount);
    }
}
static void CallOnConversationUserInputStatusChanged(OnConversationUserInputStatusChangedFn fn, void* userData, const char* change) {
    if (fn != NULL) {
        fn(userData, change);
    }
}

typedef struct {
	void* userData;
    OnSyncServerStartFn OnSyncServerStart;
    OnSyncServerFinishFn OnSyncServerFinish;
    OnSyncServerProgressFn OnSyncServerProgress;
    OnSyncServerFailedFn OnSyncServerFailed;
    OnNewConversationFn OnNewConversation;
    OnConversationChangedFn OnConversationChanged;
    OnTotalUnreadMessageCountChangedFn OnTotalUnreadMessageCountChanged;
    OnConversationUserInputStatusChangedFn OnConversationUserInputStatusChanged;
} ConversationListener;

typedef void (*OnRecvNewMessageFn)(void* userData, const char* message);
typedef void (*OnRecvC2CReadReceiptFn)(void* userData, const char* msgReceiptList);
typedef void (*OnNewRecvMessageRevokedFn)(void* userData, const char* messageRevoked);
typedef void (*OnRecvOfflineNewMessageFn)(void* userData, const char* message);
typedef void (*OnMsgDeletedFn)(void* userData, const char* message);
typedef void (*OnRecvOnlineOnlyMessageFn)(void* userData, const char* message);

static void CallOnRecvNewMessage(OnRecvNewMessageFn fn, void* userData, const char* message) {
    if (fn != NULL) {
        fn(userData, message);
    }
}
static void CallOnRecvC2CReadReceipt(OnRecvC2CReadReceiptFn fn, void* userData, const char* msgReceiptList) {
    if (fn != NULL) {
        fn(userData, msgReceiptList);
    }
}
static void CallOnNewRecvMessageRevoked(OnNewRecvMessageRevokedFn fn, void* userData, const char* messageRevoked) {
    if (fn != NULL) {
        fn(userData, messageRevoked);
    }
}
static void CallOnRecvOfflineNewMessage(OnRecvOfflineNewMessageFn fn, void* userData, const char* message) {
    if (fn != NULL) {
        fn(userData, message);
    }
}
static void CallOnMsgDeleted(OnMsgDeletedFn fn, void* userData, const char* message) {
    if (fn != NULL) {
        fn(userData, message);
    }
}
static void CallOnRecvOnlineOnlyMessage(OnRecvOnlineOnlyMessageFn fn, void* userData, const char* message) {
    if (fn != NULL) {
        fn(userData, message);
    }
}

typedef struct {
	void* userData;
    OnRecvNewMessageFn OnRecvNewMessage;
    OnRecvC2CReadReceiptFn OnRecvC2CReadReceipt;
    OnNewRecvMessageRevokedFn OnNewRecvMessageRevoked;
    OnRecvOfflineNewMessageFn OnRecvOfflineNewMessage;
    OnMsgDeletedFn OnMsgDeleted;
    OnRecvOnlineOnlyMessageFn OnRecvOnlineOnlyMessage;
} AdvancedMsgListener;

typedef void (*OnRecvNewMessagesFn)(void* userData, const char* messageList);
typedef void (*OnRecvOfflineNewMessagesFn)(void* userData, const char* messageList);

static void CallOnRecvNewMessages(OnRecvNewMessagesFn fn, void* userData, const char* messageList) {
    if (fn != NULL) {
        fn(userData, messageList);
    }
}
static void CallOnRecvOfflineNewMessages(OnRecvOfflineNewMessagesFn fn, void* userData, const char* messageList) {
    if (fn != NULL) {
        fn(userData, messageList);
    }
}

typedef struct {
    void* userData;
    OnRecvNewMessagesFn OnRecvNewMessages;
    OnRecvOfflineNewMessagesFn OnRecvOfflineNewMessages;
} BatchMsgListener;

typedef void (*OnSelfInfoUpdatedFn)(void* userData, const char* userInfo);
typedef void (*OnUserStatusChangedFn)(void* userData, const char* userOnlineStatus);
typedef void (*OnUserCommandAddFn)(void* userData, const char* userCommand);
typedef void (*OnUserCommandDeleteFn)(void* userData, const char* userCommand);
typedef void (*OnUserCommandUpdateFn)(void* userData, const char* userCommand);

static void CallOnSelfInfoUpdated(OnSelfInfoUpdatedFn fn, void* userData, const char* userInfo) {
    if (fn != NULL) {
        fn(userData, userInfo);
    }
}
static void CallOnUserStatusChanged(OnUserStatusChangedFn fn, void* userData, const char* userOnlineStatus) {
    if (fn != NULL) {
        fn(userData, userOnlineStatus);
    }
}
static void CallOnUserCommandAdd(OnUserCommandAddFn fn, void* userData, const char* userCommand) {
    if (fn != NULL) {
        fn(userData, userCommand);
    }
}
static void CallOnUserCommandDelete(OnUserCommandDeleteFn fn, void* userData, const char* userCommand) {
    if (fn != NULL) {
        fn(userData, userCommand);
    }
}
static void CallOnUserCommandUpdate(OnUserCommandUpdateFn fn, void* userData, const char* userCommand) {
    if (fn != NULL) {
        fn(userData, userCommand);
    }
}

typedef struct {
	void* userData;
    OnSelfInfoUpdatedFn OnSelfInfoUpdated;
    OnUserStatusChangedFn OnUserStatusChanged;
	OnUserCommandAddFn OnUserCommandAdd;
	OnUserCommandDeleteFn OnUserCommandDelete;
	OnUserCommandUpdateFn OnUserCommandUpdate;
} UserListener;

typedef void (*OnFriendApplicationAddedFn)(void* userData, const char* friendApplication);
typedef void (*OnFriendApplicationDeletedFn)(void* userData, const char* friendApplication);
typedef void (*OnFriendApplicationAcceptedFn)(void* userData, const char* friendApplication);
typedef void (*OnFriendApplicationRejectedFn)(void* userData, const char* friendApplication);
typedef void (*OnFriendAddedFn)(void* userData, const char* friendInfo);
typedef void (*OnFriendDeletedFn)(void* userData, const char* friendInfo);
typedef void (*OnFriendInfoChangedFn)(void* userData, const char* friendInfo);
typedef void (*OnBlackAddedFn)(void* userData, const char* blackInfo);
typedef void (*OnBlackDeletedFn)(void* userData, const char* blackInfo);

static void CallOnFriendApplicationAdded(OnFriendApplicationAddedFn fn, void* userData, const char* friendApplication) {
    if (fn != NULL) {
        fn(userData, friendApplication);
    }
}
static void CallOnFriendApplicationDeleted(OnFriendApplicationDeletedFn fn, void* userData, const char* friendApplication) {
    if (fn != NULL) {
        fn(userData, friendApplication);
    }
}
static void CallOnFriendApplicationAccepted(OnFriendApplicationAcceptedFn fn, void* userData, const char* friendApplication) {
    if (fn != NULL) {
        fn(userData, friendApplication);
    }
}
static void CallOnFriendApplicationRejected(OnFriendApplicationRejectedFn fn, void* userData, const char* friendApplication) {
    if (fn != NULL) {
        fn(userData, friendApplication);
    }
}
static void CallOnFriendAdded(OnFriendAddedFn fn, void* userData, const char* friendInfo) {
    if (fn != NULL) {
        fn(userData, friendInfo);
    }
}
static void CallOnFriendDeleted(OnFriendDeletedFn fn, void* userData, const char* friendInfo) {
    if (fn != NULL) {
        fn(userData, friendInfo);
    }
}
static void CallOnFriendInfoChanged(OnFriendInfoChangedFn fn, void* userData, const char* friendInfo) {
    if (fn != NULL) {
        fn(userData, friendInfo);
    }
}
static void CallOnBlackAdded(OnBlackAddedFn fn, void* userData, const char* blackInfo) {
    if (fn != NULL) {
        fn(userData, blackInfo);
    }
}
static void CallOnBlackDeleted(OnBlackDeletedFn fn, void* userData, const char* blackInfo) {
    if (fn != NULL) {
        fn(userData, blackInfo);
    }
}

typedef struct {
	void* userData;
    OnFriendApplicationAddedFn OnFriendApplicationAdded;
    OnFriendApplicationDeletedFn OnFriendApplicationDeleted;
    OnFriendApplicationAcceptedFn OnFriendApplicationAccepted;
    OnFriendApplicationRejectedFn OnFriendApplicationRejected;
    OnFriendAddedFn OnFriendAdded;
    OnFriendDeletedFn OnFriendDeleted;
    OnFriendInfoChangedFn OnFriendInfoChanged;
    OnBlackAddedFn OnBlackAdded;
    OnBlackDeletedFn OnBlackDeleted;
} FriendshipListener;

typedef void (*OnRecvCustomBusinessMessageFn)(void* userData, const char* businessMessage);

static void CallOnRecvCustomBusinessMessage(OnRecvCustomBusinessMessageFn fn, void* userData, const char* businessMessage) {
    if (fn != NULL) {
        fn(userData, businessMessage);
    }
}

typedef struct {
	void* userData;
    OnRecvCustomBusinessMessageFn OnRecvCustomBusinessMessage;
} CustomBusinessListener;

typedef void (*OnMessageKvInfoChangedFn)(void* userData, const char* messageChangedList);

static void CallOnMessageKvInfoChanged(OnMessageKvInfoChangedFn fn, void* userData, const char* messageChangedList) {
    if (fn != NULL) {
        fn(userData, messageChangedList);
    }
}

typedef struct {
	void* userData;
    OnMessageKvInfoChangedFn OnMessageKvInfoChanged;
} MessageKvInfoListener;

typedef void (*OnUploadLogProgressFn)(void* userData, int64_t current, int64_t size);

static void CallOnUploadLogProgress(OnUploadLogProgressFn fn, void* userData, int64_t current, int64_t size) {
    if (fn != NULL) {
        fn(userData, current, size);
    }
}

typedef struct {
	void* userData;
    OnUploadLogProgressFn OnProgress;
} UploadLogProgressCallback;

typedef void (*OpenFn)(void* userData, int64_t size);
typedef void (*PartSizeFn)(void* userData, int64_t partSize, int num);
typedef void (*HashPartProgressFn)(void* userData, int index, int64_t size, const char* partHash);
typedef void (*HashPartCompleteFn)(void* userData, const char* partsHash, const char* fileHash);
typedef void (*UploadIDFn)(void* userData, const char* uploadID);
typedef void (*UploadPartCompleteFn)(void* userData, int index, int64_t partSize, const char* partHash);
typedef void (*UploadCompleteFn)(void* userData, int64_t fileSize, int64_t streamSize, int64_t storageSize);
typedef void (*CompleteFn)(void* userData, int64_t size, const char* url, int typ);

static void CallOpen(OpenFn fn, void* userData, int64_t size) {
    if (fn != NULL) {
        fn(userData, size);
    }
}
static void CallPartSize(PartSizeFn fn, void* userData, int64_t partSize, int num) {
    if (fn != NULL) {
        fn(userData, partSize, num);
    }
}
static void CallHashPartProgress(HashPartProgressFn fn, void* userData, int index, int64_t size, const char* partHash) {
    if (fn != NULL) {
        fn(userData, index, size, partHash);
    }
}
static void CallHashPartComplete(HashPartCompleteFn fn, void* userData, const char* partsHash, const char* fileHash) {
    if (fn != NULL) {
        fn(userData, partsHash, fileHash);
    }
}
static void CallUploadID(UploadIDFn fn, void* userData, const char* uploadID) {
    if (fn != NULL) {
        fn(userData, uploadID);
    }
}
static void CallUploadPartComplete(UploadPartCompleteFn fn, void* userData, int index, int64_t partSize, const char* partHash) {
    if (fn != NULL) {
        fn(userData, index, partSize, partHash);
    }
}
static void CallUploadComplete(UploadCompleteFn fn, void* userData, int64_t fileSize, int64_t streamSize, int64_t storageSize) {
    if (fn != NULL) {
        fn(userData, fileSize, streamSize, storageSize);
    }
}
static void CallComplete(CompleteFn fn, void* userData, int64_t size, const char* url, int typ) {
    if (fn != NULL) {
        fn(userData, size, url, typ);
    }
}

typedef struct {
	void* userData;
    OpenFn Open;
    PartSizeFn PartSize;
    HashPartProgressFn HashPartProgress;
    HashPartCompleteFn HashPartComplete;
    UploadIDFn UploadID;
    UploadPartCompleteFn UploadPartComplete;
    UploadCompleteFn UploadComplete;
    CompleteFn Complete;
} UploadFileCallback;
*/
import "C"

import (
	"sync"
	"unsafe"

	open_im_sdk "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk"
)

//export FreeString
func FreeString(str *C.char) {
	if str != nil {
		C.free(unsafe.Pointer(str))
	}
}

type goBaseCallback struct {
	cb C.BaseCallback
}

func (g *goBaseCallback) OnError(errCode int32, errMsg string) {
	if g.cb.OnError != nil {
		cstr := C.CString(errMsg)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnError(g.cb.OnError, g.cb.userData, C.int32_t(errCode), cstr)
	}
}

func (g *goBaseCallback) OnSuccess(data string) {
	if g.cb.OnSuccess != nil {
		cstr := C.CString(data)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnSuccess(g.cb.OnSuccess, g.cb.userData, cstr)
	}
}

func cBool(b C.int) bool {
	return b != 0
}

// start conversation_msg.go

//export GetAllConversationList
func GetAllConversationList(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetAllConversationList(goCb, C.GoString(operationID))
}

//export GetConversationListSplit
func GetConversationListSplit(cb C.BaseCallback, operationID *C.char, offset C.int, count C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetConversationListSplit(goCb, C.GoString(operationID), int(offset), int(count))
}

//export GetOneConversation
func GetOneConversation(cb C.BaseCallback, operationID *C.char, sessionType C.int, sourceID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetOneConversation(goCb, C.GoString(operationID), int32(sessionType), C.GoString(sourceID))
}

//export GetMultipleConversation
func GetMultipleConversation(cb C.BaseCallback, operationID *C.char, conversationIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetMultipleConversation(goCb, C.GoString(operationID), C.GoString(conversationIDList))
}

//export SetConversation
func SetConversation(cb C.BaseCallback, operationID *C.char, conversationID *C.char, req *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetConversation(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(req))
}

//export HideConversation
func HideConversation(cb C.BaseCallback, operationID *C.char, conversationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.HideConversation(goCb, C.GoString(operationID), C.GoString(conversationID))
}

//export SetConversationDraft
func SetConversationDraft(cb C.BaseCallback, operationID *C.char, conversationID *C.char, draftText *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetConversationDraft(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(draftText))
}

//export GetTotalUnreadMsgCount
func GetTotalUnreadMsgCount(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetTotalUnreadMsgCount(goCb, C.GoString(operationID))
}

type goSendMsgCallback struct {
	cb C.SendMsgCallback
}

func (g *goSendMsgCallback) OnError(errCode int32, errMsg string) {
	if g.cb.OnError != nil {
		cstr := C.CString(errMsg)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnError(g.cb.OnError, g.cb.userData, C.int32_t(errCode), cstr)
	}
}

func (g *goSendMsgCallback) OnSuccess(data string) {
	if g.cb.OnSuccess != nil {
		cstr := C.CString(data)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnSuccess(g.cb.OnSuccess, g.cb.userData, cstr)
	}
}

func (g *goSendMsgCallback) OnProgress(progress int) {
	if g.cb.OnProgress != nil {
		C.CallOnProgress(g.cb.OnProgress, g.cb.userData, C.int(progress))
	}
}

//export SendMessage
func SendMessage(cb C.SendMsgCallback, operationID *C.char, message *C.char, recvID *C.char, groupID *C.char, offlinePushInfo *C.char, isOnlineOnly C.int) {
	goCb := &goSendMsgCallback{cb: cb}
	open_im_sdk.SendMessage(goCb, C.GoString(operationID), C.GoString(message), C.GoString(recvID), C.GoString(groupID), C.GoString(offlinePushInfo), cBool(isOnlineOnly))
}

//export SendMessageNotOss
func SendMessageNotOss(cb C.SendMsgCallback, operationID *C.char, message *C.char, recvID *C.char, groupID *C.char, offlinePushInfo *C.char, isOnlineOnly C.int) {
	goCb := &goSendMsgCallback{cb: cb}
	open_im_sdk.SendMessageNotOss(goCb, C.GoString(operationID), C.GoString(message), C.GoString(recvID), C.GoString(groupID), C.GoString(offlinePushInfo), cBool(isOnlineOnly))
}

//export FindMessageList
func FindMessageList(cb C.BaseCallback, operationID *C.char, findMessageOptions *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.FindMessageList(goCb, C.GoString(operationID), C.GoString(findMessageOptions))
}

//export GetAdvancedHistoryMessageList
func GetAdvancedHistoryMessageList(cb C.BaseCallback, operationID *C.char, getMessageOptions *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetAdvancedHistoryMessageList(goCb, C.GoString(operationID), C.GoString(getMessageOptions))
}

//export GetAdvancedHistoryMessageListReverse
func GetAdvancedHistoryMessageListReverse(cb C.BaseCallback, operationID *C.char, getMessageOptions *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetAdvancedHistoryMessageListReverse(goCb, C.GoString(operationID), C.GoString(getMessageOptions))
}

//export RevokeMessage
func RevokeMessage(cb C.BaseCallback, operationID *C.char, conversationID *C.char, clientMsgID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.RevokeMessage(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(clientMsgID))
}

//export TypingStatusUpdate
func TypingStatusUpdate(cb C.BaseCallback, operationID *C.char, recvID *C.char, msgTip *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.TypingStatusUpdate(goCb, C.GoString(operationID), C.GoString(recvID), C.GoString(msgTip))
}

//export MarkConversationMessageAsRead
func MarkConversationMessageAsRead(cb C.BaseCallback, operationID *C.char, conversationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.MarkConversationMessageAsRead(goCb, C.GoString(operationID), C.GoString(conversationID))
}

//export MarkAllConversationMessageAsRead
func MarkAllConversationMessageAsRead(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.MarkAllConversationMessageAsRead(goCb, C.GoString(operationID))
}

//export MarkMessagesAsReadByMsgID
func MarkMessagesAsReadByMsgID(cb C.BaseCallback, operationID *C.char, conversationID *C.char, clientMsgIDs *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.MarkMessagesAsReadByMsgID(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(clientMsgIDs))
}

//export DeleteMessageFromLocalStorage
func DeleteMessageFromLocalStorage(cb C.BaseCallback, operationID *C.char, conversationID *C.char, clientMsgID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteMessageFromLocalStorage(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(clientMsgID))
}

//export DeleteMessage
func DeleteMessage(cb C.BaseCallback, operationID *C.char, conversationID *C.char, clientMsgID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteMessage(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(clientMsgID))
}

//export HideAllConversations
func HideAllConversations(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.HideAllConversations(goCb, C.GoString(operationID))
}

//export DeleteAllMsgFromLocalAndSvr
func DeleteAllMsgFromLocalAndSvr(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteAllMsgFromLocalAndSvr(goCb, C.GoString(operationID))
}

//export DeleteAllMsgFromLocal
func DeleteAllMsgFromLocal(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteAllMsgFromLocal(goCb, C.GoString(operationID))
}

//export ClearConversationAndDeleteAllMsg
func ClearConversationAndDeleteAllMsg(cb C.BaseCallback, operationID *C.char, conversationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.ClearConversationAndDeleteAllMsg(goCb, C.GoString(operationID), C.GoString(conversationID))
}

//export DeleteConversationAndDeleteAllMsg
func DeleteConversationAndDeleteAllMsg(cb C.BaseCallback, operationID *C.char, conversationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteConversationAndDeleteAllMsg(goCb, C.GoString(operationID), C.GoString(conversationID))
}

//export InsertSingleMessageToLocalStorage
func InsertSingleMessageToLocalStorage(cb C.BaseCallback, operationID *C.char, message *C.char, recvID *C.char, sendID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.InsertSingleMessageToLocalStorage(goCb, C.GoString(operationID), C.GoString(message), C.GoString(recvID), C.GoString(sendID))
}

//export InsertGroupMessageToLocalStorage
func InsertGroupMessageToLocalStorage(cb C.BaseCallback, operationID *C.char, message *C.char, groupID *C.char, sendID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.InsertGroupMessageToLocalStorage(goCb, C.GoString(operationID), C.GoString(message), C.GoString(groupID), C.GoString(sendID))
}

//export SearchLocalMessages
func SearchLocalMessages(cb C.BaseCallback, operationID *C.char, searchParam *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SearchLocalMessages(goCb, C.GoString(operationID), C.GoString(searchParam))
}

//export SetMessageLocalEx
func SetMessageLocalEx(cb C.BaseCallback, operationID *C.char, conversationID *C.char, clientMsgID *C.char, localEx *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetMessageLocalEx(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(clientMsgID), C.GoString(localEx))
}

//export SearchConversation
func SearchConversation(cb C.BaseCallback, operationID *C.char, searchParam *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SearchConversation(goCb, C.GoString(operationID), C.GoString(searchParam))
}

//export ChangeInputStates
func ChangeInputStates(cb C.BaseCallback, operationID *C.char, conversationID *C.char, focus C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.ChangeInputStates(goCb, C.GoString(operationID), C.GoString(conversationID), cBool(focus))
}

//export GetInputStates
func GetInputStates(cb C.BaseCallback, operationID *C.char, conversationID *C.char, userID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetInputStates(goCb, C.GoString(operationID), C.GoString(conversationID), C.GoString(userID))
}

// NOTE: 返回的 *C.char 由 C 侧调用 FreeStringC 释放

//export GetAtAllTag
func GetAtAllTag(operationID *C.char) *C.char {
	s := open_im_sdk.GetAtAllTag(C.GoString(operationID))
	return C.CString(s)
}

//export CreateAdvancedTextMessage
func CreateAdvancedTextMessage(operationID *C.char, text *C.char, messageEntityList *C.char) *C.char {
	s := open_im_sdk.CreateAdvancedTextMessage(C.GoString(operationID), C.GoString(text), C.GoString(messageEntityList))
	return C.CString(s)
}

//export CreateTextAtMessage
func CreateTextAtMessage(operationID *C.char, text *C.char, atUserList *C.char, atUsersInfo *C.char, message *C.char) *C.char {
	s := open_im_sdk.CreateTextAtMessage(C.GoString(operationID), C.GoString(text), C.GoString(atUserList), C.GoString(atUsersInfo), C.GoString(message))
	return C.CString(s)
}

//export CreateTextMessage
func CreateTextMessage(operationID *C.char, text *C.char) *C.char {
	s := open_im_sdk.CreateTextMessage(C.GoString(operationID), C.GoString(text))
	return C.CString(s)
}

//export CreateLocationMessage
func CreateLocationMessage(operationID *C.char, description *C.char, longitude C.double, latitude C.double) *C.char {
	s := open_im_sdk.CreateLocationMessage(C.GoString(operationID), C.GoString(description), float64(longitude), float64(latitude))
	return C.CString(s)
}

//export CreateCustomMessage
func CreateCustomMessage(operationID *C.char, data *C.char, extension *C.char, description *C.char) *C.char {
	s := open_im_sdk.CreateCustomMessage(C.GoString(operationID), C.GoString(data), C.GoString(extension), C.GoString(description))
	return C.CString(s)
}

//export CreateQuoteMessage
func CreateQuoteMessage(operationID *C.char, text *C.char, message *C.char) *C.char {
	s := open_im_sdk.CreateQuoteMessage(C.GoString(operationID), C.GoString(text), C.GoString(message))
	return C.CString(s)
}

//export CreateAdvancedQuoteMessage
func CreateAdvancedQuoteMessage(operationID *C.char, text *C.char, message *C.char, messageEntityList *C.char) *C.char {
	s := open_im_sdk.CreateAdvancedQuoteMessage(C.GoString(operationID), C.GoString(text), C.GoString(message), C.GoString(messageEntityList))
	return C.CString(s)
}

//export CreateCardMessage
func CreateCardMessage(operationID *C.char, cardInfo *C.char) *C.char {
	s := open_im_sdk.CreateCardMessage(C.GoString(operationID), C.GoString(cardInfo))
	return C.CString(s)
}

//export CreateVideoMessageFromFullPath
func CreateVideoMessageFromFullPath(operationID *C.char, videoFullPath *C.char, videoType *C.char, duration C.longlong, snapshotFullPath *C.char) *C.char {
	s := open_im_sdk.CreateVideoMessageFromFullPath(C.GoString(operationID), C.GoString(videoFullPath), C.GoString(videoType), int64(duration), C.GoString(snapshotFullPath))
	return C.CString(s)
}

//export CreateImageMessageFromFullPath
func CreateImageMessageFromFullPath(operationID *C.char, imageFullPath *C.char) *C.char {
	s := open_im_sdk.CreateImageMessageFromFullPath(C.GoString(operationID), C.GoString(imageFullPath))
	return C.CString(s)
}

//export CreateSoundMessageFromFullPath
func CreateSoundMessageFromFullPath(operationID *C.char, soundPath *C.char, duration C.longlong) *C.char {
	s := open_im_sdk.CreateSoundMessageFromFullPath(C.GoString(operationID), C.GoString(soundPath), int64(duration))
	return C.CString(s)
}

//export CreateFileMessageFromFullPath
func CreateFileMessageFromFullPath(operationID *C.char, fileFullPath *C.char, fileName *C.char) *C.char {
	s := open_im_sdk.CreateFileMessageFromFullPath(C.GoString(operationID), C.GoString(fileFullPath), C.GoString(fileName))
	return C.CString(s)
}

//export CreateImageMessage
func CreateImageMessage(operationID *C.char, imagePath *C.char) *C.char {
	s := open_im_sdk.CreateImageMessage(C.GoString(operationID), C.GoString(imagePath))
	return C.CString(s)
}

//export CreateImageMessageByURL
func CreateImageMessageByURL(operationID *C.char, sourcePath *C.char, sourcePicture *C.char, bigPicture *C.char, snapshotPicture *C.char) *C.char {
	s := open_im_sdk.CreateImageMessageByURL(C.GoString(operationID), C.GoString(sourcePath), C.GoString(sourcePicture), C.GoString(bigPicture), C.GoString(snapshotPicture))
	return C.CString(s)
}

//export CreateSoundMessageByURL
func CreateSoundMessageByURL(operationID *C.char, soundBaseInfo *C.char) *C.char {
	s := open_im_sdk.CreateSoundMessageByURL(C.GoString(operationID), C.GoString(soundBaseInfo))
	return C.CString(s)
}

//export CreateSoundMessage
func CreateSoundMessage(operationID *C.char, soundPath *C.char, duration C.longlong) *C.char {
	s := open_im_sdk.CreateSoundMessage(C.GoString(operationID), C.GoString(soundPath), int64(duration))
	return C.CString(s)
}

//export CreateVideoMessageByURL
func CreateVideoMessageByURL(operationID *C.char, videoBaseInfo *C.char) *C.char {
	s := open_im_sdk.CreateVideoMessageByURL(C.GoString(operationID), C.GoString(videoBaseInfo))
	return C.CString(s)
}

//export CreateVideoMessage
func CreateVideoMessage(operationID *C.char, videoPath *C.char, videoType *C.char, duration C.longlong, snapshotPath *C.char) *C.char {
	s := open_im_sdk.CreateVideoMessage(C.GoString(operationID), C.GoString(videoPath), C.GoString(videoType), int64(duration), C.GoString(snapshotPath))
	return C.CString(s)
}

//export CreateFileMessageByURL
func CreateFileMessageByURL(operationID *C.char, fileBaseInfo *C.char) *C.char {
	s := open_im_sdk.CreateFileMessageByURL(C.GoString(operationID), C.GoString(fileBaseInfo))
	return C.CString(s)
}

//export CreateFileMessage
func CreateFileMessage(operationID *C.char, filePath *C.char, fileName *C.char) *C.char {
	s := open_im_sdk.CreateFileMessage(C.GoString(operationID), C.GoString(filePath), C.GoString(fileName))
	return C.CString(s)
}

//export CreateMergerMessage
func CreateMergerMessage(operationID *C.char, messageList *C.char, title *C.char, summaryList *C.char) *C.char {
	s := open_im_sdk.CreateMergerMessage(C.GoString(operationID), C.GoString(messageList), C.GoString(title), C.GoString(summaryList))
	return C.CString(s)
}

//export CreateFaceMessage
func CreateFaceMessage(operationID *C.char, index C.int, data *C.char) *C.char {
	s := open_im_sdk.CreateFaceMessage(C.GoString(operationID), int(index), C.GoString(data))
	return C.CString(s)
}

//export CreateForwardMessage
func CreateForwardMessage(operationID *C.char, m *C.char) *C.char {
	s := open_im_sdk.CreateForwardMessage(C.GoString(operationID), C.GoString(m))
	return C.CString(s)
}

//export GetConversationIDBySessionType
func GetConversationIDBySessionType(operationID *C.char, sourceID *C.char, sessionType C.int) *C.char {
	s := open_im_sdk.GetConversationIDBySessionType(C.GoString(operationID), C.GoString(sourceID), int(sessionType))
	return C.CString(s)
}

// end conversation_msg.go

// start group.go

//export CreateGroup
func CreateGroup(cb C.BaseCallback, operationID, groupReqInfo *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.CreateGroup(goCb, C.GoString(operationID), C.GoString(groupReqInfo))
}

//export JoinGroup
func JoinGroup(cb C.BaseCallback, operationID, groupID, reqMsg *C.char, joinSource C.int, ex *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.JoinGroup(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(reqMsg), int32(joinSource), C.GoString(ex))
}

//export QuitGroup
func QuitGroup(cb C.BaseCallback, operationID, groupID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.QuitGroup(goCb, C.GoString(operationID), C.GoString(groupID))
}

//export DismissGroup
func DismissGroup(cb C.BaseCallback, operationID, groupID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DismissGroup(goCb, C.GoString(operationID), C.GoString(groupID))
}

//export ChangeGroupMute
func ChangeGroupMute(cb C.BaseCallback, operationID, groupID *C.char, isMute C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.ChangeGroupMute(goCb, C.GoString(operationID), C.GoString(groupID), isMute != 0)
}

//export ChangeGroupMemberMute
func ChangeGroupMemberMute(cb C.BaseCallback, operationID, groupID, userID *C.char, mutedSeconds C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.ChangeGroupMemberMute(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(userID), int(mutedSeconds))
}

//export TransferGroupOwner
func TransferGroupOwner(cb C.BaseCallback, operationID, groupID, newOwnerUserID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.TransferGroupOwner(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(newOwnerUserID))
}

//export KickGroupMember
func KickGroupMember(cb C.BaseCallback, operationID, groupID, reason, userIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.KickGroupMember(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(reason), C.GoString(userIDList))
}

//export SetGroupInfo
func SetGroupInfo(cb C.BaseCallback, operationID, groupInfo *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetGroupInfo(goCb, C.GoString(operationID), C.GoString(groupInfo))
}

//export SetGroupMemberInfo
func SetGroupMemberInfo(cb C.BaseCallback, operationID, groupMemberInfo *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetGroupMemberInfo(goCb, C.GoString(operationID), C.GoString(groupMemberInfo))
}

//export GetJoinedGroupList
func GetJoinedGroupList(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetJoinedGroupList(goCb, C.GoString(operationID))
}

//export GetJoinedGroupListPage
func GetJoinedGroupListPage(cb C.BaseCallback, operationID *C.char, offset, count C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetJoinedGroupListPage(goCb, C.GoString(operationID), int32(offset), int32(count))
}

//export GetSpecifiedGroupsInfo
func GetSpecifiedGroupsInfo(cb C.BaseCallback, operationID, groupIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetSpecifiedGroupsInfo(goCb, C.GoString(operationID), C.GoString(groupIDList))
}

//export SearchGroups
func SearchGroups(cb C.BaseCallback, operationID, searchParam *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SearchGroups(goCb, C.GoString(operationID), C.GoString(searchParam))
}

//export GetGroupMemberOwnerAndAdmin
func GetGroupMemberOwnerAndAdmin(cb C.BaseCallback, operationID, groupID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetGroupMemberOwnerAndAdmin(goCb, C.GoString(operationID), C.GoString(groupID))
}

//export GetGroupMemberListByJoinTimeFilter
func GetGroupMemberListByJoinTimeFilter(cb C.BaseCallback, operationID, groupID *C.char, offset, count C.int, joinTimeBegin, joinTimeEnd C.longlong, filterUserIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetGroupMemberListByJoinTimeFilter(goCb, C.GoString(operationID), C.GoString(groupID), int32(offset), int32(count), int64(joinTimeBegin), int64(joinTimeEnd), C.GoString(filterUserIDList))
}

//export GetSpecifiedGroupMembersInfo
func GetSpecifiedGroupMembersInfo(cb C.BaseCallback, operationID, groupID, userIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetSpecifiedGroupMembersInfo(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(userIDList))
}

//export GetGroupMemberList
func GetGroupMemberList(cb C.BaseCallback, operationID, groupID *C.char, filter, offset, count C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetGroupMemberList(goCb, C.GoString(operationID), C.GoString(groupID), int32(filter), int32(offset), int32(count))
}

//export GetGroupApplicationListAsRecipient
func GetGroupApplicationListAsRecipient(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetGroupApplicationListAsRecipient(goCb, C.GoString(operationID))
}

//export GetGroupApplicationListAsApplicant
func GetGroupApplicationListAsApplicant(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetGroupApplicationListAsApplicant(goCb, C.GoString(operationID))
}

//export SearchGroupMembers
func SearchGroupMembers(cb C.BaseCallback, operationID, searchParam *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SearchGroupMembers(goCb, C.GoString(operationID), C.GoString(searchParam))
}

//export IsJoinGroup
func IsJoinGroup(cb C.BaseCallback, operationID, groupID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.IsJoinGroup(goCb, C.GoString(operationID), C.GoString(groupID))
}

//export GetUsersInGroup
func GetUsersInGroup(cb C.BaseCallback, operationID, groupID, userIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetUsersInGroup(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(userIDList))
}

//export InviteUserToGroup
func InviteUserToGroup(cb C.BaseCallback, operationID, groupID, reason, userIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.InviteUserToGroup(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(reason), C.GoString(userIDList))
}

//export AcceptGroupApplication
func AcceptGroupApplication(cb C.BaseCallback, operationID, groupID, fromUserID, handleMsg *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.AcceptGroupApplication(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(fromUserID), C.GoString(handleMsg))
}

//export RefuseGroupApplication
func RefuseGroupApplication(cb C.BaseCallback, operationID, groupID, fromUserID, handleMsg *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.RefuseGroupApplication(goCb, C.GoString(operationID), C.GoString(groupID), C.GoString(fromUserID), C.GoString(handleMsg))
}

// end group.go

// start init_login.go

type goConnListener struct {
	cb C.ConnListener
}

func (g *goConnListener) OnConnecting() {
	if g.cb.OnConnecting != nil {
		C.CallOnConnecting(g.cb.OnConnecting, g.cb.userData)
	}
}

func (g *goConnListener) OnConnectSuccess() {
	if g.cb.OnConnectSuccess != nil {
		C.CallOnConnectSuccess(g.cb.OnConnectSuccess, g.cb.userData)
	}
}

func (g *goConnListener) OnConnectFailed(errCode int32, errMsg string) {
	if g.cb.OnConnectFailed != nil {
		cstr := C.CString(errMsg)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnConnectFailed(g.cb.OnConnectFailed, g.cb.userData, C.int32_t(errCode), cstr)
	}
}

func (g *goConnListener) OnKickedOffline() {
	if g.cb.OnKickedOffline != nil {
		C.CallOnKickedOffline(g.cb.OnKickedOffline, g.cb.userData)
	}
}

func (g *goConnListener) OnUserTokenExpired() {
	if g.cb.OnUserTokenExpired != nil {
		C.CallOnUserTokenExpired(g.cb.OnUserTokenExpired, g.cb.userData)
	}
}

func (g *goConnListener) OnUserTokenInvalid(errMsg string) {
	if g.cb.OnUserTokenInvalid != nil {
		cstr := C.CString(errMsg)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnUserTokenInvalid(g.cb.OnUserTokenInvalid, g.cb.userData, cstr)
	}
}

//export InitSDK
func InitSDK(listener C.ConnListener, operationID *C.char, config *C.char) C.int {
	goListener := &goConnListener{cb: listener}
	ok := open_im_sdk.InitSDK(goListener, C.GoString(operationID), C.GoString(config))
	if ok {
		return 1
	}
	return 0
}

//export UnInitSDK
func UnInitSDK(operationID *C.char) {
	open_im_sdk.UnInitSDK(C.GoString(operationID))
}

//export GetSdkVersion
func GetSdkVersion() *C.char {
	return C.CString(open_im_sdk.GetSdkVersion())
}

//export GetLoginUserID
func GetLoginUserID() *C.char {
	return C.CString(open_im_sdk.GetLoginUserID())
}

//export GetLoginStatus
func GetLoginStatus(operationID *C.char) C.int {
	return C.int(open_im_sdk.GetLoginStatus(C.GoString(operationID)))
}

//export Login
func Login(cb C.BaseCallback, operationID *C.char, userID *C.char, token *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.Login(goCb, C.GoString(operationID), C.GoString(userID), C.GoString(token))
}

//export Logout
func Logout(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.Logout(goCb, C.GoString(operationID))
}

//export SetAppBackgroundStatus
func SetAppBackgroundStatus(cb C.BaseCallback, operationID *C.char, isBackground C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetAppBackgroundStatus(goCb, C.GoString(operationID), isBackground != 0)
}

//export NetworkStatusChanged
func NetworkStatusChanged(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.NetworkStatusChanged(goCb, C.GoString(operationID))
}

// end init_login.go

// start listener.go

type goGroupListener struct {
	cb C.GroupListener
}

func (g *goGroupListener) OnJoinedGroupAdded(groupInfo string) {
	if g.cb.OnJoinedGroupAdded != nil {
		cstr := C.CString(groupInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnJoinedGroupAdded(g.cb.OnJoinedGroupAdded, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnJoinedGroupDeleted(groupInfo string) {
	if g.cb.OnJoinedGroupDeleted != nil {
		cstr := C.CString(groupInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnJoinedGroupDeleted(g.cb.OnJoinedGroupDeleted, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupMemberAdded(groupMemberInfo string) {
	if g.cb.OnGroupMemberAdded != nil {
		cstr := C.CString(groupMemberInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupMemberAdded(g.cb.OnGroupMemberAdded, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupMemberDeleted(groupMemberInfo string) {
	if g.cb.OnGroupMemberDeleted != nil {
		cstr := C.CString(groupMemberInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupMemberDeleted(g.cb.OnGroupMemberDeleted, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupApplicationAdded(groupApplication string) {
	if g.cb.OnGroupApplicationAdded != nil {
		cstr := C.CString(groupApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupApplicationAdded(g.cb.OnGroupApplicationAdded, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupApplicationDeleted(groupApplication string) {
	if g.cb.OnGroupApplicationDeleted != nil {
		cstr := C.CString(groupApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupApplicationDeleted(g.cb.OnGroupApplicationDeleted, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupInfoChanged(groupInfo string) {
	if g.cb.OnGroupInfoChanged != nil {
		cstr := C.CString(groupInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupInfoChanged(g.cb.OnGroupInfoChanged, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupDismissed(groupInfo string) {
	if g.cb.OnGroupDismissed != nil {
		cstr := C.CString(groupInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupDismissed(g.cb.OnGroupDismissed, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupMemberInfoChanged(groupMemberInfo string) {
	if g.cb.OnGroupMemberInfoChanged != nil {
		cstr := C.CString(groupMemberInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupMemberInfoChanged(g.cb.OnGroupMemberInfoChanged, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupApplicationAccepted(groupApplication string) {
	if g.cb.OnGroupApplicationAccepted != nil {
		cstr := C.CString(groupApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupApplicationAccepted(g.cb.OnGroupApplicationAccepted, g.cb.userData, cstr)
	}
}

func (g *goGroupListener) OnGroupApplicationRejected(groupApplication string) {
	if g.cb.OnGroupApplicationRejected != nil {
		cstr := C.CString(groupApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnGroupApplicationRejected(g.cb.OnGroupApplicationRejected, g.cb.userData, cstr)
	}
}

//export SetGroupListener
func SetGroupListener(listener C.GroupListener) {
	goListener := &goGroupListener{cb: listener}
	open_im_sdk.SetGroupListener(goListener)
}

type goConversationListener struct {
	cb C.ConversationListener
}

func (g *goConversationListener) OnSyncServerStart(reinstalled bool) {
	if g.cb.OnSyncServerStart != nil {
		val := 0
		if reinstalled {
			val = 1
		}
		C.CallOnSyncServerStart(g.cb.OnSyncServerStart, g.cb.userData, C.int(val))
	}
}

func (g *goConversationListener) OnSyncServerFinish(reinstalled bool) {
	if g.cb.OnSyncServerFinish != nil {
		val := 0
		if reinstalled {
			val = 1
		}
		C.CallOnSyncServerFinish(g.cb.OnSyncServerFinish, g.cb.userData, C.int(val))
	}
}

func (g *goConversationListener) OnSyncServerProgress(progress int) {
	if g.cb.OnSyncServerProgress != nil {
		C.CallOnSyncServerProgress(g.cb.OnSyncServerProgress, g.cb.userData, C.int(progress))
	}
}

func (g *goConversationListener) OnSyncServerFailed(reinstalled bool) {
	if g.cb.OnSyncServerFailed != nil {
		val := 0
		if reinstalled {
			val = 1
		}
		C.CallOnSyncServerFailed(g.cb.OnSyncServerFailed, g.cb.userData, C.int(val))
	}
}

func (g *goConversationListener) OnNewConversation(conversationList string) {
	if g.cb.OnNewConversation != nil {
		cstr := C.CString(conversationList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnNewConversation(g.cb.OnNewConversation, g.cb.userData, cstr)
	}
}

func (g *goConversationListener) OnConversationChanged(conversationList string) {
	if g.cb.OnConversationChanged != nil {
		cstr := C.CString(conversationList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnConversationChanged(g.cb.OnConversationChanged, g.cb.userData, cstr)
	}
}

func (g *goConversationListener) OnTotalUnreadMessageCountChanged(totalUnreadCount int32) {
	if g.cb.OnTotalUnreadMessageCountChanged != nil {
		C.CallOnTotalUnreadMessageCountChanged(g.cb.OnTotalUnreadMessageCountChanged, g.cb.userData, C.int32_t(totalUnreadCount))
	}
}

func (g *goConversationListener) OnConversationUserInputStatusChanged(change string) {
	if g.cb.OnConversationUserInputStatusChanged != nil {
		cstr := C.CString(change)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnConversationUserInputStatusChanged(g.cb.OnConversationUserInputStatusChanged, g.cb.userData, cstr)
	}
}

//export SetConversationListener
func SetConversationListener(listener C.ConversationListener) {
	goListener := &goConversationListener{cb: listener}
	open_im_sdk.SetConversationListener(goListener)
}

type goAdvancedMsgListener struct {
	cb C.AdvancedMsgListener
}

func (g *goAdvancedMsgListener) OnRecvNewMessage(message string) {
	if g.cb.OnRecvNewMessage != nil {
		cstr := C.CString(message)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvNewMessage(g.cb.OnRecvNewMessage, g.cb.userData, cstr)
	}
}

func (g *goAdvancedMsgListener) OnRecvC2CReadReceipt(msgReceiptList string) {
	if g.cb.OnRecvC2CReadReceipt != nil {
		cstr := C.CString(msgReceiptList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvC2CReadReceipt(g.cb.OnRecvC2CReadReceipt, g.cb.userData, cstr)
	}
}

func (g *goAdvancedMsgListener) OnNewRecvMessageRevoked(messageRevoked string) {
	if g.cb.OnNewRecvMessageRevoked != nil {
		cstr := C.CString(messageRevoked)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnNewRecvMessageRevoked(g.cb.OnNewRecvMessageRevoked, g.cb.userData, cstr)
	}
}

func (g *goAdvancedMsgListener) OnRecvOfflineNewMessage(message string) {
	if g.cb.OnRecvOfflineNewMessage != nil {
		cstr := C.CString(message)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvOfflineNewMessage(g.cb.OnRecvOfflineNewMessage, g.cb.userData, cstr)
	}
}

func (g *goAdvancedMsgListener) OnMsgDeleted(message string) {
	if g.cb.OnMsgDeleted != nil {
		cstr := C.CString(message)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnMsgDeleted(g.cb.OnMsgDeleted, g.cb.userData, cstr)
	}
}

func (g *goAdvancedMsgListener) OnRecvOnlineOnlyMessage(message string) {
	if g.cb.OnRecvOnlineOnlyMessage != nil {
		cstr := C.CString(message)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvOnlineOnlyMessage(g.cb.OnRecvOnlineOnlyMessage, g.cb.userData, cstr)
	}
}

//export SetAdvancedMsgListener
func SetAdvancedMsgListener(listener C.AdvancedMsgListener) {
	goListener := &goAdvancedMsgListener{cb: listener}
	open_im_sdk.SetAdvancedMsgListener(goListener)
}

type goBatchMsgListener struct {
	cb C.BatchMsgListener
}

func (g *goBatchMsgListener) OnRecvNewMessages(messageList string) {
	if g.cb.OnRecvNewMessages != nil {
		cstr := C.CString(messageList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvNewMessages(g.cb.OnRecvNewMessages, g.cb.userData, cstr)
	}
}

func (g *goBatchMsgListener) OnRecvOfflineNewMessages(messageList string) {
	if g.cb.OnRecvOfflineNewMessages != nil {
		cstr := C.CString(messageList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvOfflineNewMessages(g.cb.OnRecvOfflineNewMessages, g.cb.userData, cstr)
	}
}

//export SetBatchMsgListener
func SetBatchMsgListener(listener C.BatchMsgListener) {
	goListener := &goBatchMsgListener{cb: listener}
	open_im_sdk.SetBatchMsgListener(goListener)
}

type goUserListener struct {
	cb C.UserListener
}

func (g *goUserListener) OnSelfInfoUpdated(userInfo string) {
	if g.cb.OnSelfInfoUpdated != nil {
		cstr := C.CString(userInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnSelfInfoUpdated(g.cb.OnSelfInfoUpdated, g.cb.userData, cstr)
	}
}

func (g *goUserListener) OnUserStatusChanged(userOnlineStatus string) {
	if g.cb.OnUserStatusChanged != nil {
		cstr := C.CString(userOnlineStatus)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnUserStatusChanged(g.cb.OnUserStatusChanged, g.cb.userData, cstr)
	}
}

func (g *goUserListener) OnUserCommandAdd(userCommand string) {
	if g.cb.OnUserCommandAdd != nil {
		cstr := C.CString(userCommand)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnUserCommandAdd(g.cb.OnUserCommandAdd, g.cb.userData, cstr)
	}
}

func (g *goUserListener) OnUserCommandDelete(userCommand string) {
	if g.cb.OnUserCommandDelete != nil {
		cstr := C.CString(userCommand)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnUserCommandDelete(g.cb.OnUserCommandDelete, g.cb.userData, cstr)
	}
}

func (g *goUserListener) OnUserCommandUpdate(userCommand string) {
	if g.cb.OnUserCommandUpdate != nil {
		cstr := C.CString(userCommand)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnUserCommandUpdate(g.cb.OnUserCommandUpdate, g.cb.userData, cstr)
	}
}

//export SetUserListener
func SetUserListener(listener C.UserListener) {
	goListener := &goUserListener{cb: listener}
	open_im_sdk.SetUserListener(goListener)
}

type goFriendshipListener struct {
	cb C.FriendshipListener
}

func (g *goFriendshipListener) OnFriendApplicationAdded(friendApplication string) {
	if g.cb.OnFriendApplicationAdded != nil {
		cstr := C.CString(friendApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendApplicationAdded(g.cb.OnFriendApplicationAdded, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendApplicationDeleted(friendApplication string) {
	if g.cb.OnFriendApplicationDeleted != nil {
		cstr := C.CString(friendApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendApplicationDeleted(g.cb.OnFriendApplicationDeleted, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendApplicationAccepted(friendApplication string) {
	if g.cb.OnFriendApplicationAccepted != nil {
		cstr := C.CString(friendApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendApplicationAccepted(g.cb.OnFriendApplicationAccepted, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendApplicationRejected(friendApplication string) {
	if g.cb.OnFriendApplicationRejected != nil {
		cstr := C.CString(friendApplication)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendApplicationRejected(g.cb.OnFriendApplicationRejected, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendAdded(friendInfo string) {
	if g.cb.OnFriendAdded != nil {
		cstr := C.CString(friendInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendAdded(g.cb.OnFriendAdded, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendDeleted(friendInfo string) {
	if g.cb.OnFriendDeleted != nil {
		cstr := C.CString(friendInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendDeleted(g.cb.OnFriendDeleted, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnFriendInfoChanged(friendInfo string) {
	if g.cb.OnFriendInfoChanged != nil {
		cstr := C.CString(friendInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnFriendInfoChanged(g.cb.OnFriendInfoChanged, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnBlackAdded(blackInfo string) {
	if g.cb.OnBlackAdded != nil {
		cstr := C.CString(blackInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnBlackAdded(g.cb.OnBlackAdded, g.cb.userData, cstr)
	}
}

func (g *goFriendshipListener) OnBlackDeleted(blackInfo string) {
	if g.cb.OnBlackDeleted != nil {
		cstr := C.CString(blackInfo)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnBlackDeleted(g.cb.OnBlackDeleted, g.cb.userData, cstr)
	}
}

//export SetFriendListener
func SetFriendListener(listener C.FriendshipListener) {
	goListener := &goFriendshipListener{cb: listener}
	open_im_sdk.SetFriendListener(goListener)
}

type goCustomBusinessListener struct {
	cb C.CustomBusinessListener
}

func (g *goCustomBusinessListener) OnRecvCustomBusinessMessage(businessMessage string) {
	if g.cb.OnRecvCustomBusinessMessage != nil {
		cstr := C.CString(businessMessage)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnRecvCustomBusinessMessage(g.cb.OnRecvCustomBusinessMessage, g.cb.userData, cstr)
	}
}

//export SetCustomBusinessListener
func SetCustomBusinessListener(listener C.CustomBusinessListener) {
	goListener := &goCustomBusinessListener{cb: listener}
	open_im_sdk.SetCustomBusinessListener(goListener)
}

type goMessageKvInfoListener struct {
	cb C.MessageKvInfoListener
}

func (g *goMessageKvInfoListener) OnMessageKvInfoChanged(messageChangedList string) {
	if g.cb.OnMessageKvInfoChanged != nil {
		cstr := C.CString(messageChangedList)
		defer C.free(unsafe.Pointer(cstr))
		C.CallOnMessageKvInfoChanged(g.cb.OnMessageKvInfoChanged, g.cb.userData, cstr)
	}
}

//export SetMessageKvInfoListener
func SetMessageKvInfoListener(listener C.MessageKvInfoListener) {
	goListener := &goMessageKvInfoListener{cb: listener}
	open_im_sdk.SetMessageKvInfoListener(goListener)
}

// end listener.go

// start online.go

//export SubscribeUsersStatus
func SubscribeUsersStatus(cb C.BaseCallback, operationID *C.char, userIDs *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SubscribeUsersStatus(goCb, C.GoString(operationID), C.GoString(userIDs))
}

//export UnsubscribeUsersStatus
func UnsubscribeUsersStatus(cb C.BaseCallback, operationID *C.char, userIDs *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.UnsubscribeUsersStatus(goCb, C.GoString(operationID), C.GoString(userIDs))
}

//export GetSubscribeUsersStatus
func GetSubscribeUsersStatus(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetSubscribeUsersStatus(goCb, C.GoString(operationID))
}

//export GetUserStatus
func GetUserStatus(cb C.BaseCallback, operationID *C.char, userIDs *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetUserStatus(goCb, C.GoString(operationID), C.GoString(userIDs))
}

// end online.go

// start relation.go

//export GetSpecifiedFriendsInfo
func GetSpecifiedFriendsInfo(cb C.BaseCallback, operationID *C.char, userIDList *C.char, filterBlack C.int) {
	goCb := &goBaseCallback{cb: cb}
	goFilterBlack := cBool(filterBlack)
	open_im_sdk.GetSpecifiedFriendsInfo(goCb, C.GoString(operationID), C.GoString(userIDList), goFilterBlack)
}

//export GetFriendList
func GetFriendList(cb C.BaseCallback, operationID *C.char, filterBlack C.int) {
	goCb := &goBaseCallback{cb: cb}
	goFilterBlack := cBool(filterBlack)
	open_im_sdk.GetFriendList(goCb, C.GoString(operationID), goFilterBlack)
}

//export GetFriendListPage
func GetFriendListPage(cb C.BaseCallback, operationID *C.char, offset C.int32_t, count C.int32_t, filterBlack C.int) {
	goCb := &goBaseCallback{cb: cb}
	goFilterBlack := cBool(filterBlack)
	open_im_sdk.GetFriendListPage(goCb, C.GoString(operationID), int32(offset), int32(count), goFilterBlack)
}

//export SearchFriends
func SearchFriends(cb C.BaseCallback, operationID *C.char, searchParam *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SearchFriends(goCb, C.GoString(operationID), C.GoString(searchParam))
}

//export CheckFriend
func CheckFriend(cb C.BaseCallback, operationID *C.char, userIDList *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.CheckFriend(goCb, C.GoString(operationID), C.GoString(userIDList))
}

//export AddFriend
func AddFriend(cb C.BaseCallback, operationID *C.char, userIDReqMsg *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.AddFriend(goCb, C.GoString(operationID), C.GoString(userIDReqMsg))
}

//export UpdateFriends
func UpdateFriends(cb C.BaseCallback, operationID *C.char, req *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.UpdateFriends(goCb, C.GoString(operationID), C.GoString(req))
}

//export DeleteFriend
func DeleteFriend(cb C.BaseCallback, operationID *C.char, friendUserID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteFriend(goCb, C.GoString(operationID), C.GoString(friendUserID))
}

//export GetFriendApplicationListAsRecipient
func GetFriendApplicationListAsRecipient(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetFriendApplicationListAsRecipient(goCb, C.GoString(operationID))
}

//export GetFriendApplicationListAsApplicant
func GetFriendApplicationListAsApplicant(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetFriendApplicationListAsApplicant(goCb, C.GoString(operationID))
}

//export AcceptFriendApplication
func AcceptFriendApplication(cb C.BaseCallback, operationID *C.char, userIDHandleMsg *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.AcceptFriendApplication(goCb, C.GoString(operationID), C.GoString(userIDHandleMsg))
}

//export RefuseFriendApplication
func RefuseFriendApplication(cb C.BaseCallback, operationID *C.char, userIDHandleMsg *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.RefuseFriendApplication(goCb, C.GoString(operationID), C.GoString(userIDHandleMsg))
}

//export AddBlack
func AddBlack(cb C.BaseCallback, operationID *C.char, blackUserID *C.char, ex *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.AddBlack(goCb, C.GoString(operationID), C.GoString(blackUserID), C.GoString(ex))
}

//export GetBlackList
func GetBlackList(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetBlackList(goCb, C.GoString(operationID))
}

//export RemoveBlack
func RemoveBlack(cb C.BaseCallback, operationID *C.char, removeUserID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.RemoveBlack(goCb, C.GoString(operationID), C.GoString(removeUserID))
}

// end relation.go

// start third.go

//export UpdateFcmToken
func UpdateFcmToken(cb C.BaseCallback, operationID *C.char, fcmToken *C.char, expireTime C.int64_t) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.UpdateFcmToken(goCb, C.GoString(operationID), C.GoString(fcmToken), int64(expireTime))
}

//export SetAppBadge
func SetAppBadge(cb C.BaseCallback, operationID *C.char, appUnreadCount C.int32_t) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetAppBadge(goCb, C.GoString(operationID), int32(appUnreadCount))
}

type goUploadLogProgressCallback struct {
	cb C.UploadLogProgressCallback
}

func (g *goUploadLogProgressCallback) OnProgress(current int64, size int64) {
	if g.cb.OnProgress != nil {
		C.CallOnUploadLogProgress(g.cb.OnProgress, g.cb.userData, C.int64_t(current), C.int64_t(size))
	}
}

//export UploadLogs
func UploadLogs(cb C.BaseCallback, operationID *C.char, line C.int, ex *C.char, progress C.UploadLogProgressCallback) {
	goCb := &goBaseCallback{cb: cb}
	goProgress := &goUploadLogProgressCallback{cb: progress}
	open_im_sdk.UploadLogs(goCb, C.GoString(operationID), int(line), C.GoString(ex), goProgress)
}

//export Logs
func Logs(cb C.BaseCallback, operationID *C.char, logLevel C.int, file *C.char, line C.int, msgs *C.char, err *C.char, keyAndValue *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.Logs(goCb, C.GoString(operationID), int(logLevel), C.GoString(file), int(line), C.GoString(msgs), C.GoString(err), C.GoString(keyAndValue))
}

type goUploadFileCallback struct {
	cb C.UploadFileCallback
}

func (g *goUploadFileCallback) Open(size int64) {
	if g.cb.Open != nil {
		C.CallOpen(g.cb.Open, g.cb.userData, C.int64_t(size))
	}
}

func (g *goUploadFileCallback) PartSize(partSize int64, num int) {
	if g.cb.PartSize != nil {
		C.CallPartSize(g.cb.PartSize, g.cb.userData, C.int64_t(partSize), C.int(num))
	}
}

func (g *goUploadFileCallback) HashPartProgress(index int, size int64, partHash string) {
	if g.cb.HashPartProgress != nil {
		cstr := C.CString(partHash)
		defer C.free(unsafe.Pointer(cstr))
		C.CallHashPartProgress(g.cb.HashPartProgress, g.cb.userData, C.int(index), C.int64_t(size), cstr)
	}
}

func (g *goUploadFileCallback) HashPartComplete(partsHash string, fileHash string) {
	if g.cb.HashPartComplete != nil {
		cParts := C.CString(partsHash)
		defer C.free(unsafe.Pointer(cParts))
		cFile := C.CString(fileHash)
		defer C.free(unsafe.Pointer(cFile))
		C.CallHashPartComplete(g.cb.HashPartComplete, g.cb.userData, cParts, cFile)
	}
}

func (g *goUploadFileCallback) UploadID(uploadID string) {
	if g.cb.UploadID != nil {
		cstr := C.CString(uploadID)
		defer C.free(unsafe.Pointer(cstr))
		C.CallUploadID(g.cb.UploadID, g.cb.userData, cstr)
	}
}

func (g *goUploadFileCallback) UploadPartComplete(index int, partSize int64, partHash string) {
	if g.cb.UploadPartComplete != nil {
		cstr := C.CString(partHash)
		defer C.free(unsafe.Pointer(cstr))
		C.CallUploadPartComplete(g.cb.UploadPartComplete, g.cb.userData, C.int(index), C.int64_t(partSize), cstr)
	}
}

func (g *goUploadFileCallback) UploadComplete(fileSize int64, streamSize int64, storageSize int64) {
	if g.cb.UploadComplete != nil {
		C.CallUploadComplete(g.cb.UploadComplete, g.cb.userData, C.int64_t(fileSize), C.int64_t(streamSize), C.int64_t(storageSize))
	}
}

func (g *goUploadFileCallback) Complete(size int64, url string, typ int) {
	if g.cb.Complete != nil {
		cstr := C.CString(url)
		defer C.free(unsafe.Pointer(cstr))
		C.CallComplete(g.cb.Complete, g.cb.userData, C.int64_t(size), cstr, C.int(typ))
	}
}

//export UploadFile
func UploadFile(cb C.BaseCallback, operationID *C.char, req *C.char, progress C.UploadFileCallback) {
	goCb := &goBaseCallback{cb: cb}
	goProgress := &goUploadFileCallback{cb: progress}
	open_im_sdk.UploadFile(goCb, C.GoString(operationID), C.GoString(req), goProgress)
}

// end third.go

// start user.go

//export GetUsersInfo
func GetUsersInfo(cb C.BaseCallback, operationID *C.char, userIDs *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetUsersInfo(goCb, C.GoString(operationID), C.GoString(userIDs))
}

//export SetSelfInfo
func SetSelfInfo(cb C.BaseCallback, operationID *C.char, userInfo *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.SetSelfInfo(goCb, C.GoString(operationID), C.GoString(userInfo))
}

//export GetSelfUserInfo
func GetSelfUserInfo(cb C.BaseCallback, operationID *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetSelfUserInfo(goCb, C.GoString(operationID))
}

//export AddUserCommand
func AddUserCommand(cb C.BaseCallback, operationID *C.char, Type C.int32_t, uuid *C.char, value *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.AddUserCommand(goCb, C.GoString(operationID), int32(Type), C.GoString(uuid), C.GoString(value))
}

//export DeleteUserCommand
func DeleteUserCommand(cb C.BaseCallback, operationID *C.char, Type C.int32_t, uuid *C.char) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.DeleteUserCommand(goCb, C.GoString(operationID), int32(Type), C.GoString(uuid))
}

//export GetAllUserCommands
func GetAllUserCommands(cb C.BaseCallback, operationID *C.char, Type C.int) {
	goCb := &goBaseCallback{cb: cb}
	open_im_sdk.GetAllUserCommands(goCb, C.GoString(operationID), int32(Type))
}

// end user.go

// start userRelated.go

var (
	mgrMutex  sync.Mutex
	mgrNextID uint64 = 1
	mgrStore         = make(map[uint64]*open_im_sdk.LoginMgr)
)

func getMgr(id uint64) *open_im_sdk.LoginMgr {
	mgrMutex.Lock()
	defer mgrMutex.Unlock()
	return mgrStore[id]
}

//export NewLoginMgr
func NewLoginMgr() C.ulonglong {
	uc := open_im_sdk.NewLoginMgr()
	mgrMutex.Lock()
	id := mgrNextID
	mgrNextID++
	mgrStore[id] = uc
	mgrMutex.Unlock()
	return C.ulonglong(id)
}

//export FreeLoginMgr
func FreeLoginMgr(id C.ulonglong) {
	mgrMutex.Lock()
	delete(mgrStore, uint64(id))
	mgrMutex.Unlock()
}

//export CheckResourceLoad
func CheckResourceLoad(id C.ulonglong, funcName *C.char, errMsg **C.char) C.int {
	mgr := getMgr(uint64(id))
	if mgr == nil {
		*errMsg = C.CString("invalid LoginMgr id")
		return -1
	}

	err := open_im_sdk.CheckResourceLoad(mgr, C.GoString(funcName))
	if err != nil {
		*errMsg = C.CString(err.Error())
		return -1
	}

	return 0
}

// end userRelated.go

func main() {

}
